package com.xiaoyang.ssyx.acl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoyang.ssyx.acl.mapper.PermissionMapper;
import com.xiaoyang.ssyx.acl.service.PermissionService;
import com.xiaoyang.ssyx.acl.service.RolePermissionService;
import com.xiaoyang.ssyx.acl.utils.PermissionHelper;
import com.xiaoyang.ssyx.model.acl.AdminRole;
import com.xiaoyang.ssyx.model.acl.Permission;
import com.xiaoyang.ssyx.model.acl.Role;
import com.xiaoyang.ssyx.model.acl.RolePermission;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @AUTHOR XiaoYang
 * @DATE 2023/6/14-16:30
 * @DESCRIPTION TODO
 */
@Service
@Slf4j
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Autowired
    private RolePermissionService rolePermissionService;

    //查询所有菜单
    @Override
    public List<Permission> queryAllPermission() {
        //1、查询所有菜单
        List<Permission> allPermissionList = baseMapper.selectList(null);
        //2、转换要求的数据格式
        List<Permission> result = PermissionHelper.buildPermission(allPermissionList);
        return result;
    }

    @Override
    public boolean removeChildById(Long id) {
        //idList 封装所有要删除菜单id
        List<Long> idList = new ArrayList<>();

        //根据当前菜单id，获取当前菜单下面所有的菜单
        this.getAllPermissionId(id,idList);

        //设置当前菜单id
        idList.add(id);

        //调用方法根据多个id删除
        int i = baseMapper.deleteBatchIds(idList);
        return i > 0;
    }

    @Override
    public Map<String,Object> getPermissionByRoleId(Long roleId) {

        //1、查询所有角权限
        List<Permission> allPermissionsList = this.queryAllPermission();

        //2、根据用户id查询用户分配角色列表
        //2.1、根据用户id查询 角色权限关系表 role_permission 查询到分配的id List<RolePermission>
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId,roleId);
        List<RolePermission> rolePermissionList = rolePermissionService.list(wrapper);


        //2.2、通过第一步返回的集合 获取到所有权限id的列表List<Long>
        List<Long> permissionIdsList = rolePermissionList.stream().map(item -> item.getPermissionId()).collect(Collectors.toList());
        //2.3、创建一个新的list集合，用户存储用户配置角色
        List<Permission> assignPermissions = new ArrayList<>();
        //2.4、遍历所有角色列表allRolesList,得到每个角色
        assignPermissions = this.getAssignPermissions(permissionIdsList,allPermissionsList,assignPermissions);

        //2.5、判断所有角色里面是否包含已经分配角色id,封装到2.3里面新的List集合

        Map<String,Object> result = new HashMap<>();

        //所有角色
        result.put("allPermissions", allPermissionsList);
        //用户已经分配的角色
        result.put("assignPermissions", assignPermissions);

        return result;
    }

    //给某个角色授权
    @Override
    public void saveAdminRole(Long roleId, Long[] permissionIds) {
        //1、删除用户己经分配过的角色数据
        //根据用户id删除admin_role表里对应的数据
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId,roleId);
        rolePermissionService.remove(wrapper);
        //2、重新分配
        //遍历多个角色id，得到每个角色id，拿着每个角色id + 用户id 添加用户角色关系表admin_role
        List<RolePermission> rolePermissionList = new ArrayList<>();
        for (Long permissionId : permissionIds) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            rolePermissionList.add(rolePermission);
        }
        rolePermissionService.saveBatch(rolePermissionList);
    }

    public List<Permission> getAssignPermissions(List<Long> permissionIdsList,List<Permission> allPermissionsList,List<Permission> assignPermissions){
        for (Permission permission: allPermissionsList) {
            //判断
            if (permissionIdsList.contains(permission.getId())){
                permissionIdsList.remove(permission.getId());
                assignPermissions.add(permission);
            }else if (permission.getChildren()!=null){
                getAssignPermissions(permissionIdsList,permission.getChildren(),assignPermissions);
            }
        }
        return assignPermissions;
    }

    //递归找当前菜单下面的所有子菜单
    //第一个参数是当前菜单id
    //第二个参数最终封装虬ist集合，包含所有菜单id
    private void getAllPermissionId(Long id, List<Long> idList) {
        LambdaQueryWrapper<Permission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Permission::getPid,id);
        List<Permission> childList = baseMapper.selectList(wrapper);

        childList.stream().forEach(item -> {
            //封装菜单id到idList.集合里面
            idList.add(item.getId());
            //递归
            this.getAllPermissionId(item.getId(), idList);
        });
    }
}
